home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-07 | 119.4 KB | 3,157 lines |
-
-
-
-
-
-
-
-
-
-
-
-
- =============================================================
-
- MB_lib V1.0
-
- Hudson and Opus message base interface library for C
-
- (c) F.W. van Wensveen 1992, 1993
-
- All Rights Reserved
-
- =============================================================
-
-
- The author of this software can be reached via E-mail
- as Frank Van.wensveen at the following addresses:
-
- 2:285/504@fidonet.org
- 27:1331/703@signet.org
- 310/902 GT Power net
- frank.van.wensveen@p0.f504.n285.z2.fidonet.org
-
- BBS: +31-10-4717477
- (V21, V22, V22b, V23, V32b, V42b, MNP2..5 - 24h/day
-
-
-
-
-
-
-
-
-
-
-
-
-
- Abstract
-
- MB_lib is a message library for use with C (calling the
- routines from other languages is, of course, also
- possible). It provides a full set of services needed to
- interface your applications with both Hudson and *.MSG-
- style message bases quite easily.
-
- This document only contains flat ASCII.
-
-
- ============================================================
- 1. INTRODUCTION
- ============================================================
-
- Why MB_lib?
- -----------
-
- One of the most important features BBSes and mail systems is the
- ability to handle electronic mail. This enables people from all
- over the world to communicate with each other against hardly more
- than the cost of (usually) local phone calls. Initially, messages
- were stored by the BBS and/or mailer software in separate files
- for each message (the well-known *.MSG files).
- Since this proved a very inefficient way of using disk space, the
- Hudson message base was developed. This message base stores all
- messages in only five files, one of which contains the total text
- of all messages in the system, while the other files act as index
- files. This system uses the available more efficiently. Today,
- the Hudson message base is used by many popular BBS and mail
- programs like Remote Access, SuperBBS, Quick BBS, FrontDoor,
- TosScan, Fmail, and lots, lots more.
-
- The Hudson message base however has the disadvantage that it is
- quite complicated to access when compared with a simple *.MSG
- file. Therefore, programmers have had more difficulty developing
- software to interface with the Hudson message base, since they
- would have to write their own, often complicated, interface
- routines first, before getting down to the meat of their
- applications.
- This library intends to remedy that by providing a full set of
- functions that allow you to interface with both Hudson and *.MSG
- message bases in a very simple way. If you're a C programmer,
- this is what you've been waiting for.
- MB_lib is a library intended for use with C. It was written using
- Borland Turbo C 2.01. and Turbo Assembler 1.5. It may also work
- with other compilers than Borland's. Of course you can also call
- the functions from other languages like Assembly, provided you
- know how. I intend to release a version for Borland C++ for
- Windows, but at the time this document was written, this version
- isn't finished yet. As far as I know this is the first library
- offering these services to the C community.
-
-
- A WORD TO THOSE WHO'D RATHER USE PASCAL
- ---------------------------------------
-
- For those with Pascal experience the story might begin to sound
- familiar. For Turbo Pascal there already is a unit with message
- base routines available. This is MSGBASE by Richard Faasen of
- Sliedrecht, The Netherlands, SysOp of InFase BBS (+31-1840-
- 21818). So if you're a Pascal programmer, you can either switch
- to C (why not?) or contact Richard.
- This library is based upon Richards original Pascal source code.
- (See also the credits at the end of this document.)
-
-
-
-
-
- 2
-
-
- FEATURES
- --------
-
- The most important features of MB_lib include (but are not
- limited to):
- * All you need to read, write, search for or kill messages.
- Writing a new message is as easy as msg_write_new ()!
- * Dynamic use of memory. Message text can have *any* size,
- the only restriction being actual memory limits. Text is
- manipulated using a 'text handle'.
- * Flexible, well-behaved, and stable. With flexible I mean
- that MB_lib won't get in the way of whatever you're doing in
- your applications (you can, for example, call MB_lib
- routines when in graphics mode without problems). MB_lib
- interfaces with your operating system in a decent way.
- * Powerful yet flexible error trapping and -handling.
- * Fully supports the Remote Access 1.11 message base locking
- technique. This means you can write programs suited for
- multi-tasking environments, as required by applications for
- Remote Access on multi-line systems.
- * Written with portability in mind. I haven't tried it as yet,
- but porting MB_lib to other platforms than MS-DOS should be
- relatively easy. The only system-dependent code is in the
- locking mechanism, which other OSes might not need.
- * No-nonsense programming style. No effort has been made to
- dress up the software or to provide flashy effects. Instead,
- the code is flexible and well-behaved enough so that you may
- do that yourself if you wish. MB_lib concentrates on
- providing fast, stable and efficient services without
- unwanted overhead (Unix people will get the idea).
-
-
- FILES IN THE PACKAGE
- --------------------
-
- The distribution package of MB_lib should contain the following
- files:
-
- MB_LIB.DOC The file you are currently reading
- MB_LIB.H The header file for MB_lib
- MB_LIBT.LIB Message base library file, Tiny model
- MB_LIBS.LIB Message base library file, Small model
- MB_LIBC.LIB Message base library file, Compact model
- MB_LIBM.LIB Message base library file, Medium model
- MB_LIBL.LIB Message base library file, Large model
- MB_LIBH.LIB Message base library file, Huge model
- *.C Example programs. Look here for tips & tricks on
- how to use the library functions in your programs.
- RALCK003.DOC The Remote Access Locking Specification version 3,
- contains details on message base locking.
-
- If you receive a version with any of these files missing, you can
- obtain a complete and uncorrupted version of MB_lib from the
- author.
-
-
-
-
-
- 3
-
-
- ABOUT THIS MANUAL
- -----------------
-
- Like the code, this manual is very straightforward. It provides
- brief insights on how the Hudson message base stores messages,
- how MB_lib handles things, and than proceeds to describe the
- library functions. In other words, this document is meant for
- people familiar with C. It is beyond the scope of this text to
- explain how functions are called or how pointers are used to
- handle data.
- The function descriptions should look familiar to anyone who has
- ever seen a C reference guide or used a man command on a Unix
- system. Basic knowledge about echomail is assumed. It wouldn't
- hurt to be familiar with FTS-0001, either.
- Sometimes examples are given in the reference section. Sometimes
- these examples are complete programs, sometimes not. The only
- purpose of these examples is to illustrate how a certain function
- works, so do not regard them as complete and functional programs.
- Example source code is included in the distribution package. It
- might really be a good idea to have a look at it.
-
-
- CREDITS
- -------
-
- Special thanks to the following people:
-
- * Richard Faasen, who wrote the original Pascal version
- (MsgBase 1.0) and gave me the Pascal source to have a go at
- it in C. Never mind the fact that he tried to convert me to
- C++ just before the beta version was finished. <grin>
- * The beta team: Feico de Boer, Olaf Westrik, Arnoud de Jonge,
- Richard Faasen, plus lots of people who made suggestions,
- offered advice, or just gave moral support.
- * John Lots for many tips and pieces of advice that (sometimes
- unintended and without his knowledge) finally ended up here.
- * Brian Pirie of Ottawa, Ontario, who knows how to write a
- hashing algorithm.
- * Everyone who replied to my questions in the FIDOnet C and
- Assembly conferences.
-
- Thank you, guys! You were all most helpful.
-
-
- DISTRIBUTION, LICENCING AND LEGALESE
- ------------------------------------
-
- The latest version of MB_lib is always available on my BBS, or
- you can request it from one of my E-mail addresses. See the front
- page of this document for details. For support, bug reports,
- etc., you can also contact me at the adresses on the front page.
- If you've written programs using this library, I'd really like to
- see them, and, if you want me to, I'll be happy to comment on
- them, and distribute the via my BBS.
-
- You may (and in fact, are encourage to) copy this software and
- distribute those copies. However, YOU MAY NOT:
-
-
- 4
-
-
- - Alter or remove any portion of the package, including this
- document, in any way.
- - Distribute it on a commercial basis. You may, however,
- charge a nominal fee not to exceed the cost of floppy disks
- and mailing costs.
- - Distribute program's you've written and compiled an
- unregistered version of MB_lib.
-
- Disclaimer: The author of this software does not accept any
- responsibility for any damage, direct or indirect, including, but
- not limited to, lost profits, lost savings, or loss or corruption
- of data, resulting from the use of, or the inability to use, this
- software.
- The software is provided 'as is', without any guarantee whatsoe-
- ver. If it works for you, fine. If it does not, too bad. If you
- try this program and your system goes to pieces, I'm not obliged
- to provide you with a tube of glue. It is the users responsibili-
- ty to make backups of important data, to carefully check out
- untested software, and to take precautions in general. So if you
- like to live dangerously, on your own head be it.
-
- The author retains the copyright to this software. This software
- is NOT in the public domain. Source code is not available, and,
- by previous agreement to other parties, it won't become available
- in the future.
-
- As to licencing: THIS IS NOT FREE SOFTWARE! I know, for many
- people this part is a giggle, but bear with me for a moment.
- You may try this software for 30 days. If you decide not to
- continue using it after the trial period of 30 days, you must
- stop using it, and you must destroy (== delete) all executables
- containing linked code from MB_lib.
- If you decide that the stuff is worth the disk space, you must
- register MB_lib. See the file REGISTER.TXT, included in this
- package, for conditions and full details on how to register.
-
-
- A note about the shareware concept
- ----------------------------------
-
- Just to make your conscience uneasy, consider this. In the past
- I've written stuff on a write-it-when-I-need-it basis. Sometimes,
- when a piece of software came in particularly handy, I decided to
- distribute it. I granted permission to anyone to use the software
- absolutely free, but I asked to be sent a netmail message, a
- postcard, or whatever, when someone decided to use my stuff.
- Since then, I've seen my programs popping up in the most unlikely
- places. So people actually use it, which gives me a real kick.
- But the number of reactions I got was very disappointing. This
- may be due to the fact that I never crippled distribution
- versions. This sounds ridiculous, and, if true, it is.
- So, when people will use my software (in which, by the way, I've
- invested a considerable amount of time), but consider it too much
- trouble to even drop me a netmail message, this may very well be
- the last program from me. This time it's really going to depend
- on user response. If I don't get any - again - then I won't spend
- too much time at the keyboard next time. On the other hand, any-
- and I mean *any* - reaction is an impulse for me to continue
-
- 5
-
-
- with projects like these. I'm sorry to put it this bluntly, but
- that's the way it is. It's all in your hands now.
- If you don't use the stuff, fine. But at least drop me a line to
- let me know what you think of it. If you're experimenting with
- this, the odds are that you know how to send me a netmail
- message. If not, ask the nearest SysOp, he'll be more than happy
- to instruct you.
- If, on the other hand, you decide to use it, even better! But
- register the stuff. It's cheap, and it will keep me at the
- keyboard to write something even better.
-
- OK - some have hinted that I didn't get any reactions because my
- documentation intro's tend to get long-winded... so let's get on
- with it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6
-
-
- ============================================================
- 2. TECHNICAL BACKGROUND INFORMATION
- ============================================================
-
-
- A BRIEF OVERVIEW OF THE HUDSON MESSAGE BASE
- -------------------------------------------
-
- It is beyond the scope of this text to explain the Hudson message
- base in detail. For those who want to know more, see the original
- specifications, if you can find 'em.
-
- The Hudson message base consists of five files. Each file
- consists of one or more records, the format of which you can find
- in the MB_lib header file. A short description follows:
-
- MSGINFO.BBS This file is the only one with a fixed size.
- It contains a single record specifying info
- regarding the entire message base: the number
- of messages in the base, the lowest and
- highest number, and the amount of messages in
- each board.
- MSGIDX.BBS Index file. This file contains a record for
- each message in the base. This record
- specifies the message number and the board it
- can be found in. This file can be used for
- searching for messages in a certain board.
- MSGTOIDX.BBS Index file. This file contains a record for
- each message in the base. The record contains
- the who_to field from the corresponding
- message header, if the message hasn't been
- received by the user yet. (Mail readers
- should overwrite this record when a message
- has been read.) This file can be used for
- searching for unread messages to a certain
- user.
- MSGHDR.BBS Index file. This file contains a record for
- each message in the base. The records contain
- the header of the corresponding message. Two
- fields in this header specify the number of
- the first text block of the message, and the
- number of text blocks.
- MSGTEXT.BBS Ah, this is the one. This file contains
- blocks of text, that make up the actual
- message text body. Start en length of
- messages are specified by fields in the
- message header.
-
- The files marked as 'Index file' have indeed an index function.
- That means that record n in one index file corresponds with
- record n in another index file. In other words, if a search for
- unread mail in MSGTOIDX.BBS results in a search hit at record
- 100, you should examine record 100 in MSGIDX.BBS to find the
- message number and board number, read record 100 in MSGHDR.BBS to
- get the message header, and examine this header to determine
- which records to read from MSGTEXT.BBS to dig up the message
- text. But you needn't worry about this - MB_lib will do that for
- you.
-
- 7
-
-
- Obviously, if one of the index files should be corrupted, this
- could mean loss of all messages in the base. Panic!
- Well, it's not as bad as that. If the files MSGHDR.BBS and
- MSGTXT.BBS are uncorrupted, the other files can be regenerated
- from these by many message base maintenance utilities.
-
-
- INTRODUCTION TO FILE LOCKING
- ----------------------------
-
- In an multi-tasking environment where two or more processes are
- sharing a single database or file, steps must be taken to prevent
- file or database corruption when writing.
- Picture this: we read a message header, update the reply link
- pointers, and write it back. Nothing wrong so far. Now try this:
- we read a file header. While we're modifying the reply link
- pointers, another process (like another instance of the BBS
- program handling another line) also reads the header. We write
- our modified header back, after which the other process does the
- same, THEREBY OVERWRITING THE MODIFICATIONS WE JUST MADE. Voila:
- one corrupt message base.
- To prevent all this, we use file locking. Before modifying one of
- the files, we lock the message base. That is: we indicate then no
- other process may write to the files at this moment. Then we
- read and modify our records, write them back, and proceed to
- unlock the message base. Other operating systems than MS-DOS
- (Unix for example) handle this for us, but if we're using MS-DOS,
- we must do it ourselves. Thanks a bundle, MicroSoft.
- MB_lib meets the official Remote Access Locking Specification.
- That means that we don't use file locking in the normal sense,
- relying on SHARE to provide the services that plain DOS doesn't
- offer. Instead, the files are locked outside their boundaries,
- while RA checks for a lock just there. In the meantime, a 0-byte
- file in RA's semaphore file directory can indicate that the
- message base must be unlocked NOW. So, as I said, it's not real
- record locking in the normal (OS) sense. See the RA locking
- specification for details.
- Should you use file locking when writing a program? YES!!! You
- may not be running a multi-line BBS, but somebody else may, so
- that your program would corrupt the message base of that system
- if you didn't use file locking.
- MB_lib provides two functions for easy locking and unlocking the
- message base, so that you won't have much trouble handling this
- properly.
- Since other processes can't write while we've got the message
- base locked, we should unlock it regularly. When performing
- several write operations at a time, for example while changing an
- entire message, you should use the following locking / unlocking
- sequences:
- Changing a message header:
- - Lock the message base
- - Read the message header
- - Modify it
- - Write it back
- - Unlock the message base
- Writing new message text when the message header exists:
- - Create message text
- - Lock the message base
-
- 8
-
-
- - Read the header
- - Write message text
- - Modify header
- - Write back header
- - Unlock message base
- The same goes for *any* write operation (create, modify, kill,
- whatever) to the message base. Lock the message base, do your
- modification, unlock, lock, do another modification, unlock.
- Always lock as short as possible. If you should need to lock the
- message base for more than 15 seconds at a time, you must take
- some special precautions. See the document RALCK003, enclosed in
- this package, for details.
-
-
- HOW TEXT IS STORED IN MEMORY
- ----------------------------
-
- The size of a message text body is unknown. The Hudson message
- base allows - in theory - for a maximum text size of 16 Mb,
- though many BBS and mail processor packages can't handle more
- than 8 or 16 kb. Therefore it is wise not to write messages
- larger than 8 kb.
- Anyway, we can't allocate a fixed data space for a message text.
- Therefore, text space is dynamically allocated.
- Text is manipulated with a so-called text handle. For the
- technically inclined: this text handle is actually a pointer to
- the beginning of a linked list of records, consisting of pointers
- to text blocks and pointers to the next record in the chain.
- Text handles are variables of type M_TEXT. You declare a text
- handle as follows:
-
- M_TEXT msgtxt; /* Text handle to manipulate message text */
-
- That's all! Text handles are returned by functions like the
- msg_read_text () and txt_new () functions. For example:
-
- msgtxt = msg_read_text (& header); /* Read message text */
-
- To dump this text to, say, the screen, you use the same text
- handle:
-
- txt_dump (msgtxt, printline, margin, NOKLUDGES);
-
- It's a simple as that!
-
-
- HOW MB_LIB HANDLES ERROR TRAPPING
- ---------------------------------
-
- This may be news to some programmers... <grin> but many things
- can go wrong while a program is running, and it is wise to check
- for errors, so that when (not if) an error occurs, the program
- can gracefully exit. Many programs, especially those written in
- Pascal for some reason, lack airtight error trapping, so that
- they sometimes exit with the highly informative message RUNTIME
- ERROR AT 1234:ABCD (or some other address). Anyway, I've labored
- to make error trapping in MB_lib as foolproof as possible.
-
-
- 9
-
-
- Since library code never should get in the way of whatever the
- application is doing, error trapping is very flexible. Library
- routines do not exit to the OS. Library codes do not print error
- messages. Nor do they generate beeps or anything else. The
- application programmer can do all this if desired.
- Every library function that can encounter an error returns a
- completion code. This code usually is zero to indicate error-free
- completion, or non-zero if an error was encountered. When
- functions are supposed to return a number (like a message or
- record number), the error completion code is -1, otherwise it is
- an integer indication the nature of the error. For example:
-
- if (msg_open ("C:\\MSGBASE"))
- error (); /* Invoke programmer-supplied error handler */
-
- The programmer has two global variables at his/her disposal, to
- determine the nature of the error. When an error occurs, these
- variables are automatically set to indicate what went wrong, and
- can be used in an error handler.
- First, there is the int errortype variable. This variable can
- have the following values:
-
- NOT_ERR (0x00) /* No error */
- MEM_ERR (0x01) /* Memory error - out of memory */
- FRD_ERR (0x02) /* File read error */
- FWR_ERR (0x03) /* File write error */
- FCR_ERR (0x04) /* File create error */
- MNO_ERR (0x05) /* Message base not open error */
- IRN_ERR (0x06) /* Invalid record no., out of bound */
- MBC_ERR (0x07) /* Msg base corrupt */
-
- THIS VALUE ALSO APPLIES TO THE FUNCTION COMPLETION CODES!
- Examining either the completion code or the errortype variable
- can be used to trap errors.
- Then there is the char errorstring [] variable. This string is
- filled with a message telling the user what went wrong, in
- readable text.
-
- Using these two variables, an error handler could look like this:
-
- void error_exit (void) {
- printf ("%cError %d accessing message base:\n%s\n",
- BELL, errortype, errorstring);
- exit (1);
- }
-
- Because MB_lib routines do not exit to the OS or print anything,
- you won't get problems when, for example, an error occurs while
- in graphics mode. On the other hand, if you always remember to
- check completion codes, you will be able to handle any kind of
- error, critical or non-critical.
-
-
- USE OF THE REGISTRATION KEY
- ---------------------------
-
- Users who register their copy of MB_lib will receive a registra-
- tion key. This key is a small file, that should be included in
-
- 10
-
-
- the program at the top of the source listing. Typically you would
- add a include "mb_lib.key" statement to your program along
- with the include statements for, say, the stdio.h file.
- That is all! The registration key does not take up extra
- code/data space in the compiled executables. The only thing you
- will notice is that the compiled program no longer displays the
- 'unregistered' message when running.
- With the key, you can recompile your programs for distribution.
-
-
- HOW MB_LIB IS DIVIDED INTO SEGMENTS
- -----------------------------------
-
- Because the whole library is a large chunk of code, it would be
- difficult to handle at once. Therefore, the library is divided
- into segments. This provides a reasonable compromise between
- efficiency and code size. If a segment isn't used, it is not
- linked to your executable.
- The functions in each segment are discussed in a separate
- chapter. The segments have the following functions:
-
- TEXT Functions to handle text
- ACCESS Functions to access the message base
- LOCK Functions to take care of message base locking to
- enable your programs to run in a multi-tasking or
- multi-line BBS environment
- MANIP Message manipulation functions
- READ Functions to read records and messages
- WRITE Functions to write records and messages
- SEARCH Functions to search for messages
- NETMAIL This segment contains all functions to handle messages
- in the *.MSG format (like netmail messages with most
- mailers).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 11
-
-
- ============================================================
- 3. TYPES, VARIABLES AND DEFINES
- ============================================================
-
- =======================
- M_TEXT
- =======================
-
- Name M_TEXT - text handle type
-
- Usage M_TEXT <handlename>
-
- Description As explained above, a text handle is used to
- manipulate message text. A variable of this type
- is returned by functions like txt_new ().
-
- See also The background information given above, and the
- reference section on the txt_new () (and other)
- functions.
-
- Example M_TEXT msgtext; /* Text handle */
-
-
- =======================
- msginfo
- =======================
-
- Name msginfo - a global MSGINFO.BBS record for various
- purposes
-
- Usage MSGINFO_RECORD msginfo;
-
- Description Since MSGINFO.BBS contains only one record, which
- can have only one value, it makes sense to define
- one global record in which this information can
- be stored. Instead of reading the file over and
- over again to a locally defined record, this
- variable provides one record which can be referred
- to when MSGINFO.BBS data is needed for any
- purpose.
-
- See also msg_read_info ();
-
-
- ========================
- errortype
- ========================
-
- Name errortype - indicate what went wrong
-
- Usage int errortype;
-
- Description The errortype variable is set when MB_lib
- encounters an error. It can have the following
- values:
-
- NOT_ERR No error
- MEM_ERR Memory error (out of memory)
-
- 12
-
-
- FRD_ERR File read error
- FWR_ERR File write error
- FCR_ERR File creation error
- MNO_ERR Message base not opened before
- accessing it
- IRN_ERR Invalid record number specified for
- read or write, attempt to access
- files outside boundaries
- MBC_ERR Message base corrupt - header
- specifies non-existent records
-
- Remarks These values also apply to the completion codes
- returned by the functions which do not return a
- record or message number. It is set when *any*
- function encounters an error. Checking it is up to
- you. However, errortype may have been set by a
- previous function after which you didn't check. In
- general, using completion codes to trap errors is
- the most reliable way.
-
- See also errorstring
-
- Example See errorstring
-
-
- ========================
- errorstring
- ========================
-
- Name errorstring - tell the user what went wrong
-
- Usage char errorstring []
-
- Description The errorstring variable is set whenever the
- errortype variable is set. It contains a string
- telling you in readable text what went wrong. The
- string is not \n terminated.
-
- Remarks See errortype
-
- See also errortype
-
- Example void errorexit (void) { /* Exit with error */
- putchar (BELL);
- printf ("MB_lib error %d: %s\n", errortype,
- errorstring);
- exit (1);
- }
-
-
- =======================
- Various defines
- =======================
-
- For your convenience, the following values have been defined in
- MB_lib.h:
-
-
-
- 13
-
-
- HCR Hard carriage return to indicate the end of
- a paragraph in messages
- SCR Soft carriage return, may be reformatted by
- message readers
- LF Line feed
- KLUDGE The kludge delimiter. If this is the first
- character on a line, the rest of that line up
- to the first HCR will be used as a kludge.
- BELL The bell character
- KLUDGES Indicates that the txt_dump () function
- should dump kludges
- NOKLUDGES Indicates that the txt_dump () function
- should not dump kludges. See txt_dump () for
- details.
-
-
- =======================
- Message attributes
- =======================
-
-
- #define MA_DELETED 0x01 /* Message attributes */
- #define MA_UNSENT 0X02
- #define MA_NETMAIL 0X04
- #define MA_PRIVATE 0X08
- #define MA_RECEIVED 0X10
- #define MA_UNMOVED 0X20
- #define MA_LOCAL 0X40
-
- #define NA_KILL 0X01 /* Hudson netmail attributes */
- #define NA_SENT 0X02
- #define NA_FILE 0X04
- #define NA_CRASH 0X08
- #define NA_RECEIPT 0X10
- #define NA_AUDIT 0X20
- #define NA_RETURN 0X40
-
- #define NM_PRIVATE 0X0001 /* Opus (*.MSG) Netmail attributes */
- #define NM_CRASH 0x0002
- #define NM_RECEIVED 0x0004
- #define NM_SENT 0x0008
- #define NM_FILE 0x0010
- #define NM_TRANSIT 0x0020
- #define NM_ORPHAN 0x0040
- #define NM_KILL 0x0080
- #define NM_LOCAL 0x0100
- #define NM_HOLD 0x0200
- #define NM_UNUSED 0x4000
- #define NM_REQUEST 0x0800
- #define NM_RECEIPT 0x1000
- #define NM_ISRECEIPT 0x2000
- #define NM_AUDIT 0x4000
- #define NM_UPDATEREQ 0x8000
-
-
-
-
-
-
- 14
-
-
- =======================
- Record structures
- =======================
-
- The following structures make up the message base file records. BEWARE!
- Since the strings in the Hudson message base are Pascal-format strings,
- you should NEVER read or write message base records yourself, but
- instead use the functions provided in MB_lib, so that the proper
- conversion can be performed.
- These structures all use C-style strings - you needn't worry about
- formats here. Just remember to use the MB_lib functions for message
- base I/O. That's what they're for, anyway, so why would you want to do
- otherwise?
-
- typedef struct { /* MSGINFO.BBS structure definition */
- unsigned int low_msg; /* Lowest msg # in message base */
- unsigned int high_msg; /* Highest msg # in message base */
- unsigned int total_msgs; /* Total # of messages in base */
- unsigned int total_on_board [200]; /* Number of msgs / board */
- } MSGINFO_RECORD;
-
- typedef struct { /* MSGIDX.BBS structure definition */
- int msg_num; /* Message # */
- unsigned char board; /* Board # where msg is stored */
- } MSGIDX_RECORD;
-
- typedef char MSGTOIDX_RECORD [36]; /* MSGTOIDX.BBS structure def. */
-
- typedef struct { /* MSGHDR.BBS structure definition */
- int msgnum; /* Message number */
- unsigned int prev_reply; /* Msg # of previous reply, 0 if no */
- unsigned int next_reply; /* Msg # of next reply, 0 if none */
- unsigned int times_read; /* # of times msg was read, UNUSED */
- unsigned int start_block; /* Record # of msg in MSGTXT.BBS */
- unsigned int num_blocks; /* # of records in MSGTXT.BBS */
- unsigned int dest_net; /* Destination net */
- unsigned int dest_node; /* Destination node */
- unsigned int orig_net; /* Origin net */
- unsigned int orig_node; /* Origin node */
- unsigned char dest_zone; /* Destination zone */
- unsigned char orig_zone; /* Origin zone */
- unsigned int cost; /* Cost (Netmail) */
- unsigned char msg_attr; /* Msg attributes. Bits as follows: */
- /* 0 : Deleted */
- /* 1 : Unsent */
- /* 2 : Netmail */
- /* 3 : Private */
- /* 4 : Received */
- /* 5 : Unmoved outgoing echo */
- /* 6 : Local */
- /* 7 : RESERVED */
- unsigned char net_attr; /* Netmail attributes. Bits follow: */
- /* 0 : Kill/Sent */
- /* 1 : Sent */
- /* 2 : File attach */
- /* 3 : Crash */
- /* 4 : Receipt request */
- /* 5 : Audit request */
-
- 15
-
-
- /* 6 : Is a return receipt */
- /* 7 : RESERVED */
- unsigned char board; /* Message board # */
- char post_time [6]; /* Time message was posted */
- char post_date [9]; /* Date message was posted */
- char who_to [36]; /* Recipient to whom msg is sent */
- char who_from [36]; /* Sender who posted message */
- char subject [73]; /* Subject line of message */
- } MSGHDR_RECORD;
-
- typedef struct { /* MSGTXT.BBS structure definition */
- unsigned char str_len; /* This string is stored in memory */
- char str_txt [255]; /* in Pascal format to reduce */
- } MSGTXT_RECORD; /* overhead, so take care! */
-
-
- /* The strings in the *.MSG file header (Opus style) aren't Pascal */
- /* type strings but have the 'normal' ASCIIZ format. */
-
- typedef struct { /* OPUS-style (*.MSG) msg format */
- char who_from [36]; /* Sender who posted message */
- char who_to [36]; /* Recipient to whom msg is sent */
- char subject [72]; /* Subject line of message */
- char datetime [20]; /* Date/time msg was last edited */
- unsigned int times_read; /* # of times message was read */
- unsigned int dest_node; /* Destination node */
- unsigned int orig_node; /* Origin node */
- unsigned int cost; /* Cost to send netmail msg */
- unsigned int orig_net; /* Origin net */
- unsigned int dest_net; /* Destination net */
- unsigned int dest_zone; /* Destination zone (These fields) */
- unsigned int orig_zone; /* Origin zone (were padded ) */
- unsigned int dest_point; /* Destination point (with 8 0's ) */
- unsigned int orig_point; /* Origin point (in FSC-0001 ) */
- unsigned int reply_to; /* Msg # to which this one replies */
- unsigned int attribute; /* Msg attributes. Bits as follows: */
- /* 0 : Private */
- /* 1 : Crash */
- /* 2 : Received */
- /* 3 : Sent */
- /* 4 : File attached */
- /* 5 : In transit */
- /* 6 : Orphan */
- /* 7 : Kill when sent */
- /* 8 : Local */
- /* 9 : Hold for pickup */
- /* 10 : UNUSED */
- /* 11 : File request */
- /* 12 : Return receipt request */
- /* 13 : Is a return receipt */
- /* 14 : Audit request */
- /* 15 : File update request */
- unsigned int next_reply; /* Next msg in reply chain */
- } NET_RECORD;
-
-
-
-
-
- 16
-
-
- ============================================================
- 4. TEXT SERVICES
- ============================================================
-
- =======================
- txt_new ()
- =======================
-
- Name txt_new - create a new message text body
-
- Usage M_TEXT txt_new (char * string);
-
- Description The txt_new () function creates a new message text
- body. This is typically the first function to call
- when starting with a new message text. It requires
- that you have defined a text handle previously.
- This function also initializes the text handle.
- The string argument may either be the first line
- of the new message text body, or may be a pointer
- to a complete null-terminated block of text.
-
- Return value Text handle, NULL if error. In case of error, the
- errortype and errorstring variables are set to
- indicate the type of error.
-
- Remarks The \n character is not translated and will be
- placed in the message text body as a line feed
- (LF). It will be ignored by message readers,
- according to specifications in FTS-0001. The \r
- character generates a Hard Carriage Return (HCR).
-
- See also txt_add (), txt_dispose ()
-
- Example See txt_add ()
-
-
- =======================
- txt_add ()
- =======================
-
- Name txt_add - add new text to an existing message text
- body.
-
- Usage int txt_add (M_TEXT texthandle, char * string);
-
- Description The txt_add () function adds text to an existing
- message text body. When starting a new message
- text body, you MUST call txt_new () first in order
- to initialize your text handle.
-
- Return value Zero to indicate success, non-zero to indicate an
- error. See the 'variables' section for completion
- codes.
-
- Remarks See txt_new ()
-
- See also txt_new ()
-
-
- 17
-
-
- Example #include "mblib.h"
-
- M_TEXT msgtext;
-
- msgtext = txt_new ("This is line one. \n");
- if (msgtext == NULL) { /* ERROR! */
- printf ("%s\n", errorstring);
- exit (1);
- }
- if (txt_add (msgtext, "This is line two!\r"))
- printf ("%s\n", errorstring);
-
-
- ========================
- txt_dispose
- ========================
-
- Name txt_dispose - dispose of a message text body
-
- Usage void txt_dispose (M_TEXT texthandle);
-
- Description The txt_dispose () function is used to dispose of
- a block of text. It releases the memory allocated
- for the text body. Call this function after you've
- finished with a text body (after processing it),
- to free memory and the text handle for future use.
-
- Return value None.
-
- See also txt_new ()
-
-
- ========================
- txt_dump
- ========================
-
- Name txt_dump - dump a message text to an output device
-
- Usage int txt_dump (M_TEXT texthandle,
- int (* output) (char *), unsigned char margin,
- unsigned char kludges);
-
- Description The txt_dump () function is used for all dumping
- and printing of message text. It is very flexible
- and can be used to print message text to the
- screen, to send it to *any* device, file, or
- whatever, or to manipulate individual text lines.
- It does so by dividing text into separate lines,
- and then calling a programmer supplied output
- routine to process that line. Because you supply
- the output routine yourself, you have complete
- control over what happens to the text.
- Text is wrapped to a specified line width (the
- margin parameter), while kludges are either
- printed or not printed, as specified by the
- kludges parameter.
- Because the syntax is a bit complicated, here's a
- list summarizing the accepted parameters:
-
- 18
-
-
- M_TEXT texthandle - this is the text handle for
- the text body you want to dump.
- int (* output) (char *) - this looks complex but
- it isn't. This parameter is the NAME (!) of the
- programmer supplied function to process a text
- line. This function should accept a pointer to
- char, and return an integer. This return value
- should be zero to indicate success or nonzero to
- indicate an error. See example below.
- unsigned char margin - this is the number of
- characters you want the text to be wrapped to
- unsigned char kludges - this is a flag which
- indicates whether to print kludges or not. It can
- have the value KLUDGES to print kludges, or
- NOKLUDGES to print no kludges.
-
- Return value 0 if success, -1 if the output routine encountered
- an error (or at least returned a non-zero value).
-
- Remarks WARNING: Because the actual output is not handled
- by MB_lib, an error encountered by the output
- routine will not set the errortype and errorstring
- variables! Error handling within the output
- routine must be handled by the programmer.
- The line passed to the output routine is not \n or
- \r terminated.
-
- Example #include "mblib.h"
- #include <stdio.h>
-
- int printline (char *); /* Always prototype */
- int saveline (char *); /* these functions! */
-
- M_TEXT msgtext;
- FILE * savefile;
-
- void main (void) {
- msgtext = txt_new ("This is line one. \n");
- if (msgtext == NULL) { /* ERROR! */
- printf ("%s\n", errorstring);
- exit (1);
- }
- if (txt_add (msgtext, "This is line two!\r")) {
- printf ("%s\n", errorstring);
- exit (1);
- }
- txt_dump (msgtext, printline, 70, NOKLUDGES);
- /* Print text to screen, margin 70 */
- if ((savefile = fopen ("TEST", "w")) == NULL)
- exit (1);
- txt_dump (msgtext, saveline, 80, KLUDGES);
- /* Save text to file, margin 80 + kludges */
- txt_dispose (msgtext);
- puts ("Done.");
- fclose (savefile);
- } /* main */
-
- /* The following functions each output text */
-
- 19
-
-
- /* one line at a time */
-
- int printline (char * line) {
- puts (line);
- return (0); /* This always works */
- } /* printline */
-
- int saveline (char * line) {
- if (!fprintf (savefile, "%s\n", line)) {
- puts ("Error saving text!");
- return (-1); /* Error writing file */
- }
- else
- return (0);
- } /* saveline */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 20
-
-
- ============================================================
- 5: MESSAGE BASE ACCESS SERVICES
- ============================================================
-
- ========================
- msg_open
- ========================
-
- Name msg_open - open the message base
-
- Usage int msg_open (char * msgbasepath);
-
- Description Before you can access the message base, you MUST
- call this function to open the message base and
- initialize the message base I/O system. If you do
- not, any attempts to access the message base will
- result in a MNO_ERR return value.
- MB_lib tries to locate the message base files in
- the path you supply. If the files don't exist,
- msg_open () will create them.
-
- Return value 0 if success, non-zero if error. See the 'varia-
- bles' section for completion codes.
-
- Remarks Attempts to open the message base when it is
- already open can't do any harm. MB_lib keeps track
- of these things, just in case you do not. :-)
- The message base path may be terminated by a
- backslash, or not.
-
- See also msg_close ()
-
- Example if (msg_open ("C:\\MSGBASE"))
- exit (1); /* Error opening message base */
- /* Your message handling goes here */
- msg_close ();
-
-
- ========================
- msg_close
- ========================
-
- Name msg_close - close the message base
-
- Usage void msg_close (void);
-
- Description msg_close closes the message base files after
- you're done with them. Closing the message base
- when it isn't open can't do any harm - MB_lib
- checks first.
-
- Remarks You don't rally need to call msg_close () before
- exiting your program. When you have opened the
- message base, MB_lib checks to see if you've
- closed them again before exiting. So if you forget
- to call msg_close (), there's no harm done. But
- from a puristic point of view, it's bad habit to
-
-
- 21
-
-
- rely on such mechanisms, it's neater to close the
- message base yourself.
-
- See also msg_open ()
-
- Example See msg_open ()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 22
-
-
- ============================================================
- 6: MESSAGE BASE LOCKING SERVICES
- ============================================================
-
- ========================
- msg_lock
- ========================
-
- Name msg_lock - lock the message base to prevent writes
- by other processes
-
- Usage int msglock (char * semapath);
-
- Description In a multi-tasking environment (like multi-line
- BBS'es) we must take precautions to prevent file
- corruption. The details on this are described
- above (see Introduction to file locking).
- The semapath string must specify the directory
- that is used by Remote Access to keep it's
- semaphore files in.
-
- Return value -1 if the there was a problem locking the message
- base, otherwise 0.
-
- Remarks If SHARE is not loaded before locking the message
- base, this won't cause an error. I guess that's
- the whole point for the rather exotic (and, to my
- taste, a little inelegant) RA locking method.
- Since msg_lock () allows for a 15 second timeout,
- locking your message base could take this long.
-
- See also msg_unlock ()
-
- Example #include "mb_lib.h"
-
- if (msg_lock == -1)
- puts ("Error locking message base");
- /* Or you could put a few retries here... */
- else {
- msg_write_new (& msgheader, msgtext);
- /* msgheader and msgtext previously inited */
- msg_unlock ();
-
-
- ========================
- msg_unlock
- ========================
-
- Name msg_unlock - unlock the message base after
- modifying it
-
- Usage void msg_unlock (void);
-
- Description Use msg_unlock () to release file locks on the
- message base, thereby enabling other processes to
- perform their write operations again.
-
- Remarks See msg_lock ()
-
- 23
-
-
-
- See also msg_lock ()
-
- Example See msg_lock ()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 24
-
-
- ============================================================
- 7: MESSAGE MANIPULATION SERVICES
- ============================================================
-
- ========================
- msg_msgnr2recnr
- ========================
-
- Name msg_msgnr2recnr - convert message number to record
- number.
-
- Usage long msg_msgnr2recnr (unsigned int msgnr);
-
- Description Message numbers are not related to record numbers
- on a 1:1 basis. Since messages may have been
- deleted from the message base, the message base
- records 0, 1, and 2 could, for example, contain
- the messages 100, 294 and 1583. This function
- converts a record number to the corresponding
- message number.
-
- Return value The record number of the message we're searching
- for, -1 if the message was not found or an error
- occurred. In the latter case the errortype and
- errorstring variables are set.
-
- Remarks If the message base contains message numbers which
- have been set to -1 (some programs do this to
- indicate that a message has been killed),
- msg_msgnr2recnr () switches to a different search
- algorithm, resulting in a slight decrease in
- performance.
-
- See also msg_recnr2msgnr ();
-
- Example #include "mb_lib.h"
-
- long recnr;
- int msgnr;
-
- printf ("Enter message number: ");
- scanf ("%d", & msgnr);
- if ((recnr = msg_msgnr2recnr (msgnr)) == -1)
- puts ("Message not found.");
- else
- printf ("Record nr. %l\n", recnr);
-
-
- ========================
- msg_recnr2msgnr
- ========================
-
- Name msg_recnr2msgnr - convert record number to message
- number.
-
- Usage unsigned int msg_recnr2msgnr (long recnr);
-
-
-
- 25
-
-
- Description This function does exactly the opposite of the
- msg_msgnr2recnr () function: it retrieves the
- message number that corresponds with a certain
- record number.
-
- Return value The message number of the message corresponding
- with the specified record, -1 if an error
- occurred. In this case the errortype an error-
- string variables are set.
-
- See also msg_msgnr2recnr ()
-
- Example #include "mb_lib.h"
-
- long recnr;
-
- puts ("Message nr: 10");
- if ((recnr = msg_recnr2msgnr (recnr)) == -1)
- puts ("Error accessing message base");
- else
- printf ("Record nr: %l\n", recnr);
-
-
- ========================
- msg_hdr_clear
- ========================
-
- Name msg_hdr_clear - clear a message header record,
- e.g. set all fields in the header to zero.
-
- Usage void msg_hdr_clear (MSGHDR_RECORD * hdr);
-
- Description A message header record contains many fields, many
- of which should be set to 0 when creating a new
- message. Because the fields in an uninitialized
- header contain unknown values, we should initiali-
- zed each field before using this header. Since
- this is very cumbersome, this function does the
- job for you.
-
- Remarks This function should always be called when
- creating a new message header, otherwise unpredic-
- table effects will occur.
-
- Example #include "mb_lib.h"
-
- MSGHDR_RECORD hdr;
-
- msg_hdr_clear (& hdr);
- strcpy (hdr.who_from, "Frank Van.wensveen");
- strcpy (hdr.who_to, "All");
- strcpy (hdr.subject, "Test"); /* That's all! */
-
- ========================
- msg_fixup4d
- ========================
-
-
-
- 26
-
-
- Name msg_fixup4d - convert the zone fields in a netmail
- header to an INTL kludge to overcome the FSC-0001
- compliance problem.
-
- Usage int msg_fixup4d (MSGHDR_RECORD * hdr, M_TEXT txt);
-
- Description FSC-0001 describes the format of a basic *.MSG
- netmail message header. Since this document dates
- from the time that only 2D addressing (net/node)
- was used, the definition had not defined any zone
- and point address fields, but instead contains a 8
- byte 'padding area'.
- The header used in this message base library is a
- variant that is widely used by a number of
- popular software packages, but not supported by
- all programs. This leads to problems. For example,
- a message entered in Remote Access addressed to
- zone 3, will be sent to the zone defined as the
- mailers primary address instead.
- To overcome this incompatibility, the INTL, FMPT
- and TOPT kludges have been defined. These kludges
- are added to the message text, usually at the top
- of the message, although at the bottom they work
- just as well. They have the following functions:
- INTL 27:1331/703 2:285/504
- indicates a message to 27:1331/703 from 2:285/504,
- FMPT 2
- indicates a message from point 2, and
- TOPT 6
- indicates a message to point 6.
- So, a message from, say, 27:1331/703.5 to
- 2:285/504.2 will contain the following kludges:
- INTL 2:285/504 27:1331/703
- FMPT 5
- TOPT 2
- while the header has to contain only 1331/703 as
- the origin address, and 285/504 as the destination
- address. It may contain more, but if the mailer
- (or any other software used to process the
- message) doesn't support use of those fields, the
- extra header information is ignored. Software that
- doesn't support these kludges simply ignores them,
- as with all other kludges.
- The msg_fixup4d function allows you to easily
- write messages that are processed correctly by
- FSC-0001 compliant software. It converts the
- undocumented zone fields in the Hudson netmail
- header into a INTL kludge, while the related
- net_fixup4d () function converts the undocumented
- zone and point fields in the *.MSG header into
- INTL, FMPT and TOPT kludges. If these fields are
- zero, however, the kludges are omitted.
-
- Return value Zero on success, nonzero on error.
-
- Remarks CAUTION: The fixup functions add text to the
- specified text handle. The text handle *MUST*
- therefore be initialized, otherwise "unpredictable
-
- 27
-
-
- results" (an euphemism for a total screwup,
- usually) will occur. You *must* have called
- txt_new () previous to calling msg_fixup4d () or
- net_fixup4d ().
-
- See also net_fixup4d ()
-
- Example #include "mb_lib.h"
-
- MSGHDR_RECORD hdr;
- M_TEXT msgtxt;
-
- msg_hdr_clear (& hdr);
- strcpy (hdr.who_from, "Frank Van.wensveen");
- strcpy (hdr.who_to, "Sysop");
- strcpy (hdr.subject, "Kludges");
- hdr.dest_zone = 27;
- hdr.orig_zone = 2;
- hdr.dest_net = 1331;
- hdr.orig_net = 285;
- hdr.dest_node = 703;
- hdr.orig_node = 504;
-
- /* Now we have two possibilities. The first: */
- msgtxt = txt_new (""); /* THIS IS VITAL!! */
- msg_fixup4d (& hdr, msgtxt); /* Add kludges */
- txt_add ("This message now contains kludges.\r");
-
- /* The second: */
- msgtxt = txt_new ("This message is kludgy!\r");
- msg_fixup4d (& hdr, msgtxt); /* Add kludges */
- /* Note the \r after the last message text! */
- /* Without it, the kludge will be ignored! */
-
- msg_write_new (& hdr, msgtxt); /* Save it */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 28
-
-
- ============================================================
- 8: MESSAGE READING SERVICES
- ============================================================
-
- ========================
- msg_read_info
- ========================
-
- Name msg_read_info - read MSGINFO.BBS into the global
- msginfo record
-
- Usage void msg_read_info (void);
-
- Description MSGINFO.BBS does not contain multiple records, but
- instead has a fixed length, and contains only one
- structure that can have only one value at a time.
- Therefore it makes sense not to read MSGINFO.BBS
- over and over again to locally defined structures,
- but instead use a global structure that can be
- used for multiple purposes. This structure is
- msginfo. See the variables section for details.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_write_info ();
-
- Example #include "mb_lib.h"
-
- /* Message base is supposed to be open */
- if (msg_read_info ())
- exit (1); /* Read error */
- printf ("Number of messages in base: ");
- printf ("%u\n", msginfo.total_msgs);
-
-
- ========================
- msg_read_hdr
- ========================
-
- Name msg_read_hdr - read a message header from a
- specified record in MSGHDR.BBS.
-
- Usage int msg_read_hdr (long recnr,
- MSGHDR_RECORD * hdr);
-
- Description This function is used to read a message header.
- Prior to reading the header, the record number of
- the message must be known. This number can be
- obtained from one of the search functions.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_write_hdr ()
-
-
- 29
-
-
- Example #include "mblib.h"
- MSGHDR_RECORD myheader;
-
- /* Reading the header in record 100: */
- if (msg_read_hdr (100, & myheader))
- exit (1); /* Read error */
- printf ("Subject: %s\n", myhdr.subject);
-
-
- ========================
- msg_read_idx
- ========================
-
- Name msg_read_idx - read a message header from a
- specified record in MSGIDX.BBS.
-
- Usage int msg_read_idx (long recnr,
- MSGIDX_RECORD * idx);
-
- Description This function is used to read a message index
- record. This record specifies the message number
- and the board number of a message in a certain
- record. Prior to reading the record, the record
- number of the message must be known. This number
- can be obtained from one of the search functions.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
-
- See also msg_write_idx ()
-
- Example #include "mblib.h"
- MSGIDX_RECORD myidx;
-
- /* Reading the index in record 100: */
- if (msg_read_idx (100, & myidx))
- exit (1); /* Read error */
- printf ("Msg nr: %d, board nr: %d",
- myidx.msg_num, myidx.board);
-
-
- ========================
- msg_read_toidx
- ========================
-
- Name msg_read_toidx - read a record from a specified
- record in MSGTOIDX.BBS.
-
- Usage int msg_read_toidx (long recnr,
- MSGTOIDX_RECORD * idx);
-
- Description This function is used to read a MSGTOIDX.BBS
- record. Prior to reading the header, the record
- number of the message must be known. This number
- can be obtained from one of the search functions.
-
-
- 30
-
-
- The obtained record specifies the user name the
- message is sent to. After the message has been
- received, this record should be overwritten by the
- message reader. As a result, the MSGTOIDX file can
- be searched for unreceived mail to a certain user.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_write_toidx ()
-
- Example #include "mblib.h"
- MSGTOIDX_RECORD addressee;
-
- /* Reading addressee from record 100: */
- if (msg_read_toidx (100, & addressee))
- exit (1); /* Read error */
- printf ("To: %s\n", addressee);
-
-
- ========================
- msg_read_text
- ========================
-
- Name msg_read_text - read the text of a message, the
- header of which is known.
-
- Usage M_TEXT msg_read_text (MSGHDR_RECORD * hdr);
-
- Description This function is used to read the text of a
- certain message. Because text is not just a single
- record, more information than just a record number
- is needed. Therefore, the message header must be
- read prior to calling this function, and a pointer
- to the corresponding message header is passed to
- this read function.
-
- Return value The text handle to be used for the text, NULL if
- an error occurred. In this case the errortype and
- errorstring variables are set.
-
- See also msg_write_text (), txt_dump ()
-
- Example #include "mb_lib.h"
- MSGHDR_RECORD msghdr; /* Header */
- M_TEXT msgtxt; /* Text handle */
-
- /* Reading message in record 100 */
- if (msg_read_hdr (100, & msghdr))
- exit (1); /* Read error */
- msgtxt = msg_read_text (& msghdr);
- if (msgtxt == NULL)
- exit (1); /* Read error */
- printf ("Message %d:\n", msghdr.msgnum);
- printf ("By: %s\nTo:%s\nRe:%s\n\n",
- msghdr.who_from, msghdr.who_to,
- msghdr.subject);
-
- 31
-
-
- txt_dump (msgtxt, printline, 70, NOKLUDGES);
- /* Printline function defined elsewhere */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 32
-
-
- ============================================================
- 9: MESSAGE WRITING SERVICES
- ============================================================
-
- ========================
- msg_write_info
- ========================
-
- Name msg_write_info - write the global msginfo record
- to MSGINFO.BBS
-
- Usage void msg_write_info (void);
-
- Description This function is much like msg_read_info, except
- that it writes the global MSGINFO.BBS record back,
- for example after it has been modified.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_read_info ();
-
- Example #include "mb_lib.h"
-
- /* Message base is supposed to be open */
- if (msg_read_info ())
- exit (1); /* Read error */
- /* The msginfo record is modified here */
- if (msg_write_info ())
- exit (1); /* Write error */
-
-
- ========================
- msg_write_hdr
- ========================
-
- Name msg_read_hdr - write a message header to a
- specified record in MSGHDR.BBS.
-
- Usage int msg_write_hdr (long recnr,
- MSGHDR_RECORD * hdr);
-
- Description This function is used to write a message header.
- Prior to writing the header, the record number of
- the message must be known. This number can be
- obtained from one of the search functions, or,
- when modifying a header, it is usually known
- before you need this function.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_read_hdr ()
-
- Example #include "mblib.h"
- MSGHDR_RECORD myheader;
-
- 33
-
-
-
- /* Modify the header in record 100: */
- if (msg_read_hdr (100, & myheader))
- exit (1); /* Read error */
- myheader.times_read ++; /* Read once more */
- if (msg_write_hdr (100, & myheader))
- exit (1); /* Write error */
-
-
- ========================
- msg_write_idx
- ========================
-
- Name msg_write_idx - write a message header to a
- specified record in MSGIDX.BBS.
-
- Usage int msg_write_idx (long recnr,
- MSGIDX_RECORD * idx);
-
- Description This function is much like msg_read_idx (), except
- that it writes a record to MSGIDX.BBS.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_read_idx ()
-
- Example #include "mblib.h"
- MSGIDX_RECORD myidx; /* Supposed to be inited */
-
- /* Writing the index to record 100: */
- if (msg_to_idx (100, & myidx))
- exit (1); /* Read error */
-
-
- ========================
- msg_write_toidx
- ========================
-
- Name msg_write_toidx - write a record to a specified
- record in MSGTOIDX.BBS.
-
- Usage int msg_write_toidx (long recnr,
- MSGTOIDX_RECORD * idx);
-
- Description This function is much like msg_read_toidx (),
- except that it writes a record to MSGIDX.BBS, for
- example after modifying it.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- See also msg_read_toidx ()
-
- Example #include "mblib.h"
- MSGTOIDX_RECORD addressee;
-
- 34
-
-
-
- /* Reading addressee from record 100: */
- if (msg_read_toidx (100, & addressee))
- exit (1); /* Read error */
- printf ("To: %s\n", addressee);
- strcpy (addressee, "* Received *");
- /* Since the msg is no longer unreceived, */
- /* mark it as such */
- if (msg_write_toidx (100, & addressee)
- exit (1); /* Write error */
-
-
- ========================
- msg_write_text
- ========================
-
- Name msg_write_text - write text to a message, either
- modifying old text or creating new text.
-
- Usage int msg_write_text (MSGHDR_RECORD * hdr,
- M_TEXT txt);
-
- Description This function is typically used to modify existing
- message text, or to add new text to a previously
- written new message header. To create entire new
- messages from scratch, you'd better use the
- msg_write_new () function.
- Whether the text is used as a replacement or as
- new text is determined by the message header
- passed to the function. If the start_block and
- num_blocks field in the message header are zero,
- the text is treated as new text (since there
- obviously isn't any old text with these field
- containing zero). Otherwise, previous text is
- replaced.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- Remarks Replaced message text blocks are not actually
- removed from the message base. You need to pack
- the message base with an external message base
- maintenance utility to do this.
-
- See also msg_read_text (), msg_write_new ()
-
- Example #include "mb_lib.h"
- MSGHDR_RECORD msghdr; /* Header */
- M_TEXT msgtxt; /* Text handle */
-
- /* Reading message in record 100 */
- if (msg_read_hdr (100, & msghdr))
- exit (1); /* Read error */
- /* Now read text, add line, write it back */
- msgtxt = msg_read_text (& msghdr);
- if (msgtxt == NULL)
- exit (1); /* Read error */
-
- 35
-
-
- if (txt_add (msgtxt, "One more line..."))
- exit (1); /* Memory error */
- if (msg_write_txt (& msghdr, msgtxt))
- exit (1); /* Error writing new text */
-
-
- ========================
- msg_write_new
- ========================
-
- Name msg_write_new - write a new message to the message
- base
-
- Usage int msg_write_new (MSGHDR_RECORD * hdr,
- M_TEXT txt);
-
- Description Ah - this is the one! This function is typically
- used to write a new message to the message base.
- Before calling this function you need to construct
- a message header and fill in the source, destina-
- tion and subject fields (in case of netmail, node
- numbers as well), fill in the board number and
- set the desired message attributes. You also need
- to create a message text. When you've got header
- and text handy, all you need is call this function
- (which will set the other header fields for you).
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- Remarks You must set unused header fields to zero - the
- msg_hdr_clear () function can be used for this. If
- you don't, unpredicted results (this being an
- euphemism for a complete screwup) could occur.
-
- See also msg_write_text (), msg_kill ()
-
- Example #include "mb_lib.h"
- MSGHDR_RECORD msghdr;
- M_TEXT msgtxt;
-
- /* Error checking left out to keep it short! */
- /* In other words, this is quick and dirty. */
- main () {
- msg_open ("C:\\MSGBASE");
- msg_hdr_clear (& msghdr);
- strcpy (msghdr.who_from, "Frank Van.wensveen");
- strcpy (msghdr.who_to, "All");
- strcpy (msghdr.subject, "See how easy it is?");
- msghdr.board = 6; /* My local echomail board */
- msghdr.msg_attr = MA_LOCAL;
- msgtxt = txt_new ("See? Writing a message is ");
- txt_add (msgtxt, "easy! Even I could do it!\r");
- msg_lock ("C:\\SEMAFORE");
- msg_write_new (& msghdr, msgtxt);
- msg_unlock ();
- msg_close ();
-
- 36
-
-
- }
-
-
- ========================
- msg_kill
- ========================
-
- Name msg_kill - kill a message
-
- Usage int msg_kill (long recnr);
-
- Description The msg_kill () function is used to kill a
- message, the record number of which is specified.
-
- Return value Zero on success, a nonzero value on error,
- indicating the nature of the error. See the
- section on error handling for result codes.
-
- Remarks A killed message is not actually removed from the
- message base. To do this, you need to pack the
- message base with an external message base
- maintenance utility.
-
- Example #include "mb_lib.h"
- long recnr;
-
- /* Killing message nr. 100 */
- recnr = msg_msgnr2recnr (100);
- if (recnr != -1)
- msg_kill (recnr);
- /* Error checking left out */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 37
-
-
- ============================================================
- 10: MESSAGE SEARCH SERVICES
- ============================================================
-
- ========================
- msg_firstinboard
- ========================
-
- Name msg_firstinboard - find the first message in the
- specified board
-
- Usage long msg_firstinboard (unsigned char board);
-
- Description This message is used to find the RECORD NUMBER of
- the first message in a certain board. You'll need
- things like this when reading all messages in a
- certain board from first to last or something
- like that.
-
- Return value The RECORD number of the first message in the
- specified board, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_lastinboard (), msg_nextinboard (),
- msg_previnboard ()
-
- Example See msg_nextinboard ();
-
-
- ========================
- msg_nextinboard
- ========================
-
- Name msg_nextinboard - find the next message in the
- same board as the message we've just read is in.
-
- Usage long msg_nextinboard (long recnr);
-
- Description After calling msg_firstinboard, we've got the
- record number of the first message in that board.
- This function finds the next message in that
- board, using the record number of the previously
- processed message as a starting point.
-
- Return value The RECORD number of the next message in the
- specified board, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_firstinboard (), msg_lastinboard (),
- msg_previnboard ();
-
- Example #include "mb_lib.h"
- long recnr;
-
- /* Listing messages in board 1 */
- recnr = msg_firstinboard (1);
-
- 38
-
-
- while (recnr != -1) {
- printf ("Message number:%d\n",
- msg_recnr2msgnr (recnr);
- recnr = msg_nextinboard (recnr);
- }
-
-
- ========================
- msg_lastinboard
- ========================
-
- Name msg_lastinboard - find the last message in the
- specified board.
-
- Usage long msg_lastinboard (unsigned char board);
-
- Description This message is identical to msg_firstinboard, but
- returns the number of the last message instead of
- the first.
-
- Return value The RECORD number of the last message in the
- specified board, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_firstinboard (), msg_nextinboard (),
- msg_previnboard ();
-
- Example See msg_previnboard ();
-
-
- ========================
- msg_previnboard
- ========================
-
- Name msg_previnboard - find the previous message in the
- same board as the message we've just read is in.
-
- Usage long msg_previnboard (long recnr);
-
- Description This function is identical to msg_nextinboard (),
- except that it searches backwards.
-
- Return value The RECORD number of the previous message in the
- specified board, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_next_inboard, msg_lastinboard (),
- msg_previnboard ();
-
- Example #include "mb_lib.h"
- long recnr;
-
- /* Backward listing messages in board 1 */
- recnr = msg_lastinboard (1);
- while (recnr != -1) {
- printf ("Message number:%d\n",
-
- 39
-
-
- msg_recnr2msgnr (recnr);
- recnr = msg_previnboard (recnr);
- }
-
-
- ========================
- msg_firstto
- ========================
-
- Name msg_firstto - find the first unreceived message to
- a certain user
-
- Usage long msg_firstto (MSGTOIDX_RECORD * idx);
-
- Description This message can be used to scan the message base
- for unreceived mail to a certain user. It scans
- MSGTOIDX.BBS for the user's name and returns the
- record number associated with a search hit. You
- can then proceed to read the message in this
- record.
- Software used for reading the unreceived messages
- should overwrite the corresponding record in
- MSGTOIDX.BBS to prevent the message from remaining
- marked as unreceived. Functions in MB_lib don't
- take care of this, the programmer must do it.
-
- Return value The RECORD number of the first message to the
- specified user, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_nextto (), msg_lastto (), msg_prevto ()
-
- Example See msg_nextto ()
-
-
- ========================
- msg_nextto
- ========================
-
- Name msg_nextto - find the next message to the same
- user as the one we just read was addressed to
-
- Usage long msg_nextto (long recnr);
-
- Description After calling msg_firstto, we've got the record
- number of the first message to a certain user.
- This function finds the next message to that
- user, using the record number of the previously
- processed message as a starting point.
-
- Return value The RECORD number of the next message to the
- specified user, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_firstto (), msg_lastto (), msg_prevto ()
-
-
- 40
-
-
- Example #include "mb_lib.h"
- long recnr;
- MSGTOIDX_RECORD toidx;
-
- strcpy (toidx, "Frank Van.wensveen");
- recnr = msg_firstto (toidx);
- puts ("Mail waiting for you:");
- while (recnr != -1) {
- printf ("Message number: %d\n",
- msg_recnr2msgnr (recnr);
- recnr = msg_nextto (recnr);
- }
-
-
- ========================
- msg_lastto
- ========================
-
- Name msg_lastto - find the last unreceived message to a
- certain user.
-
- Usage long msg_lastto (MSGTOIDX_RECORD * toidx);
-
- Description This function is identical to msg_firstto (),
- except that it searches for the last message
- instead of the first.
-
- Return value The RECORD number of the last message to the
- specified user, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_firstto (), msg_nextto (), msg_prevto ()
-
- Example See msg_prevto ()
-
-
- ========================
- msg_prevto
- ========================
-
- Name msg_prevto - find the previous message to the same
- user as the one we just read was addressed to
-
- Usage long msg_nextto (long recnr);
-
- Description This message is identical to msg_nextto (), except
- that it searches backwards.
-
- Return value The RECORD number of the previous message to the
- specified user, -1 if not found or error. In the
- latter case the errortype and errorstring
- variables are set.
-
- See also msg_firstto (), msg_lastto (), msg_nextto ()
-
- Example #include "mb_lib.h"
- long recnr;
-
- 41
-
-
- MSGTOIDX_RECORD toidx;
-
- strcpy (toidx, "Frank Van.wensveen");
- recnr = msg_lastto (toidx);
- puts ("Mail waiting for you:");
- puts ("Listed last to first")
- while (recnr != -1) {
- printf ("Message number: %d\n",
- msg_recnr2msgnr (recnr);
- recnr = msg_prevto (recnr);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 42
-
-
- ============================================================
- 11: NETMAIL (*.MSG) SERVICES
- ============================================================
- The following routines make up the net_ family. These functions
- are typically used for netmail support. But in fact any *.MSG
- base is supported, no matter what type of mail it contains.
- (Fmail for example uses *.MSG type files to store personal mail.)
-
- WARNING: though the netmail header defined in MB_LIB.H contains
- both a Zone and a Point field, these fields are not supported by
- FSC-0001. Correct interpretation of these fields by all software
- is NOT guaranteed. In fact, some programs have been verified to
- use these fields for other data. FSC-0001 (sec) specified 2D
- addressing only.
- In order to use 4D addresses which will be processed correctly by
- all software, it is recommended that you use the FMPT/TOPT and
- INTL kludges instead.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 43
-
-
- ========================
- net_first
- ========================
-
- Name net_first - get the number of the first netmail
- message in a directory.
-
- Usage int net_first (char * msgpath);
-
- Description This function is used to get the number of the
- first message in a *.MSG (Opus-style) message
- base. The path to the directory holding the *.MSG
- files is specified.
-
- Return value The number of the first message in the directory,
- 0 if error or no messages found. In this case the
- errortype and errorstring variables are set.
-
- Remarks The specified directory is supposed to contain
- *.MSG files. These message need not be netmail
- messages.
-
- See also net_last (), net_next (), net_prev ()
-
- Example See net_next ()
-
-
- ========================
- net_next
- ========================
-
- Name net_next - return the number of the message next
- to the specified one.
-
- Usage int net_next (char * msgpath, int nr);
-
- Description While net_first () return the number of the first
- message in the specified directory, this function
- returns the number of the message next to the
- specified one. Typically you'd call net_first (),
- and use the number obtained to find the next
- message until you run out of mail.
-
- Return value The number of the message in the directory next to
- the specified number, 0 if error or no messages
- found. In this case the errortype and errorstring
- variables are set.
-
- See also net_first (), net_last (), net_prev ()
-
- Example #include "mb_lib.h"
- int msgnum;
-
- msgnum = net_first ("C:\\NETMAIL");
- puts ("Netmail:");
- while (msgnum != 0) {
- printf ("%d\n", msgnum);
- msgnum = net_next (msgnum);
-
- 44
-
-
- }
-
-
- ========================
- net_last
- ========================
-
- Name net_last - get the number of the last netmail
- message in a directory.
-
- Usage int net_last (char * msgpath);
-
- Description This function is used to get the number of the
- last message in a *.MSG (Opus-style) message
- base. The path to the directory holding the *.MSG
- files is specified.
-
- Return value The number of the last message in the directory,
- 0 if error or no messages found. In this case the
- errortype and errorstring variables are set.
-
- Remarks The specified directory is supposed to contain
- *.MSG files. These message need not be netmail
- messages.
-
- See also net_first (), net_next (), net_prev ()
-
- Example See net_prev ()
-
-
- ========================
- net_prev
- ========================
-
- Name net_prev - return the number of the message
- previous to the specified one.
-
- Usage int net_prev (char * msgpath, int nr);
-
- Description While net_last () returns the number of the last
- message in the specified directory, this function
- returns the number of the message previous to the
- specified one. Typically you'd call net_last (),
- and use the number obtained to find the previous
- message until you run out of mail.
-
- Return value The number of the message in the directory
- previous to the specified number, 0 if error or
- no messages found. In this case the errortype and
- errorstring variables are set.
-
- See also net_first (), net_last (), net_next ()
-
- Example #include "mb_lib.h"
- int msgnum;
-
- msgnum = net_last ("C:\\NETMAIL");
- puts ("Netmail listed backwards:");
-
- 45
-
-
- while (msgnum != 0) {
- printf ("%d\n", msgnum);
- msgnum = net_prev (msgnum);
- }
-
-
- ========================
- net_hdr_clear
- ========================
-
- Name net_hdr_clear - clear a netmail header record,
- e.g. set all fields in the header to zero.
-
- Usage void net_hdr_clear (NET_RECORD * hdr);
-
- Description A netmail header record contains many fields, many
- of which should be set to 0 when creating a new
- message. Because the fields in an uninitialized
- header contain unknown values, we should initiali-
- zed each field before using this header. Since
- this is very cumbersome, this function does the
- job for you.
-
- Remarks This function should always be called when
- creating a new netmail header, otherwise unpredic-
- table effects will occur.
-
- Example #include "mb_lib.h"
-
- NET_RECORD hdr;
-
- net_hdr_clear (& hdr);
- strcpy (hdr.who_from, "Frank Van.wensveen");
- strcpy (hdr.who_to, "All");
- strcpy (hdr.subject, "Test");
- /* The header is now fully initialized! */
-
-
- ========================
- net_getlastread
- ========================
-
- Name net_getlastread - get the lastread pointer for the
- specified *.msg folder.
-
- Usage int net_getlastread (char * msgpath);
-
- Description To keep track of what message has been read the
- last time, most message readers / editors use a
- lastread pointer. This is a small file located in
- the message directory, which contains the number
- of the message that was read last.
- This function is used to read the lastread pointer
- for a specified message directory.
-
- Return value The number of the message that was read last or -1
- if an error was encountered. In that case the
- errortype and errorstring variables are set.
-
- 46
-
-
-
- See also net_setlastread ()
-
-
- ========================
- net_setlastread
- ========================
-
- Name net_setlastread - set the lastread pointer for the
- specified *.msg folder
-
- Usage int setlastread (char * msgpath, int lastread);
-
- Description This function is used to set the lastread pointer
- for the specified message directory to a specified
- value.
-
- Return value Zero if success, non-zero if an error was
- encountered. In this case the errortype and
- errorstring variables are set.
-
- See also net_getlastread
-
-
- ========================
- net_read_hdr
- ========================
-
- Name net_read_hdr - read a netmail header
-
- Usage int net_read_hdr (char * msgpath, int msgnr,
- NET_RECORD * hdr);
-
- Description This function is much like msg_read_hdr, in that
- it is used to read a message header.
-
- Return value Zero if success, non-zero if an error was
- encountered.
-
- See also msg_read_hdr (), net_read_text ()
-
- Example See net_read_text ()
-
-
- ========================
- net_read_text
- ========================
-
- Name net_read_text - read the text body of a netmail
- message.
-
- Usage M_TEXT net_read_text (char * msgpath, int msgnum);
-
- Description This function is much like msg_read_text, in that
- it is used to read the text body of a message.
- Combined with the net_read_hdr () function, it can
- be used for all kinds of netmail message reading
- jobs. Because text is returned by means of a text
-
- 47
-
-
- handle, all possibilities with regard to text
- manipulation apply.
-
- Return value Text handle, NULL on error. In this case the
- errortype and errorstring variables are set.
-
- See also msg_read_text (), net_read_hdr ()
-
- Example #include "mb_lib.h"
-
- M_TEXT txt;
- NET_RECORD hdr;
-
- /* Reading message nr. 10 */
- if (net_read_hdr ("C:\\NETMAIL", 10, & hdr))
- exit (1);
- txt = net_read_text ("C:\\NETMAIL, 10);
- if (txt == NULL)
- exit (1);
- txt_dump (txt, printline, 70, NOKLUDGES);
-
-
- ========================
- net_write
- ========================
-
- Name net_write - write a (netmail) message into a *.MSG
- base.
-
- Usage int net_write (char * msgpath, int msgnr,
- NET_RECORD * hdr, M_TEXT txt);
-
- Description This function is all you need to write a *.MSG
- message. Before calling the net_write () function,
- you need to determine the desired message number.
- For new messages you typically do something like
- msg_nr = net_last ("C:\\NETMAIL") + 1;.
- You also need to create a message text, the text
- handle of which is passed to the net_write ()
- function.
- Unused fields in the message header must be set to
- zero, or unpredictable results will occur. The
- net_hdr_clear () function can be used for that.
- The datetime field in the message header does not
- need to be initialized, net_write () will do that
- for you.
-
- Return value Zero on success, non-zero when an error is
- encountered. In this case the errortype and
- errorstring variables are set.
-
- See also msg_write_new ();
-
- Example #include "mb_lib.h"
- NET_RECORD msghdr;
- M_TEXT msgtxt;
-
- /* Error checking left out to keep it short! */
-
- 48
-
-
- /* In other words, this is quick and dirty. */
- main () {
- net_hdr_clear (& msghdr);
- strcpy (msghdr.who_from, "Frank Van.wensveen");
- strcpy (msghdr.who_to, "SysOp");
- strcpy (msghdr.subject, "See how easy it is?");
- msghdr.msg_attr = NM_LOCAL;
- msgtxt = txt_new ("See? Writing a netmail is ");
- txt_add (msgtxt, "easy! Even I could do it!\r");
- net_write ("C:\\NETMAIL",
- net_last ("C:\\NETMAIL") + 1,
- & msghdr, msgtxt);
- }
-
-
- ========================
- net_kill
- ========================
-
- Name net_kill - kill a *.MSG message.
-
- Usage int net_kill (char * msgpath, int msgnr);
-
- Description This function is used to kill (delete) a message
- in a *.MSG base. Unlike messages in the Hudson
- message base, *.MSG messages are physically
- deleted when killed.
-
- Return value Zero on success, non-zero if an error was
- encountered. In this case the errortype and
- errorstring variables are set.
-
-
- ========================
- net_fixup4d
- ========================
-
- Name net_fixup4d - convert the zone and point fields in
- a *.MSG netmail header into INTL and FMPT/TOPT
- kludges to overcome the FSC-0001 compliance
- problem.
-
- Usage int net_fixup4d (NET_RECORD * hdr, M_TEXT txt);
-
- Description See msg_fixup4d. The difference between Hudson
- netmail headers and *.MSG headers is that the
- latter also contain unsupported point fields. The
- Hudson netmail header does not support point
- addresses.
-
- Return value Zero on success, non-zero on error.
-
- Remarks CAUTION: The fixup functions add text to the
- specified text handle. The text handle *MUST*
- therefore be initialized, otherwise "unpredictable
- results" (an euphemism for a total screwup,
- usually) will occur. You *must* have called
-
-
- 49
-
-
- txt_new () previous to calling msg_fixup4d () or
- net_fixup4d ().
-
- See also msg_fixup4d ()
-
- Example see msg_fixup4d ().
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 50
-
-
-
-
-
-
- This page intentionally left blank.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 51